package com.chen.utils.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chen.root.base.PageData;
import com.chen.root.base.R;
import com.chen.root.oclass.TreeNode;
import com.chen.utils.entity.DataSourceInfo;
import com.chen.utils.entity.DatasourceFill;
import com.chen.utils.entity.DatasourceStrategy;
import com.chen.utils.entity.StrategyInfo;
import com.chen.utils.mapper.DataSourceInfoMapper;
import com.chen.utils.mapper.DatasourceFillMapper;
import com.chen.utils.mapper.DatasourceStrategyMapper;
import com.chen.utils.mapper.StrategyInfoMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author: ~龙~
 * @date: 2023/6/28 14:41
 **/
@Slf4j
@Validated
@RestController
@RequestMapping("/dataSource")
@Api(tags = {"数据源配置管理API"})
public class DataSourceController {

    @Resource
    private DataSourceInfoMapper dataSourceInfoMapper;
    @Resource
    private DatasourceStrategyMapper datasourceStrategyMapper;
    @Resource
    private DatasourceFillMapper datasourceFillMapper;
    @Resource
    private StrategyInfoMapper strategyInfoMapper;

    @GetMapping("/page")
    @ApiOperation("分页查询数据源配置")
    public R<PageData<DataSourceInfo>> page(Integer currentPage, Integer pageSize, String dbName){
        Page<DataSourceInfo> page = dataSourceInfoMapper.selectPage(new Page<>(currentPage, pageSize),
                Wrappers.lambdaQuery(DataSourceInfo.class)
                        .like(StrUtil.isNotBlank(dbName), DataSourceInfo::getDbName, dbName)
        );
        return R.ok(PageData.build(currentPage, pageSize, page.getTotal(), page.getRecords()));
    }

    @GetMapping("/all")
    @ApiOperation("获取所有数据源的树节点")
    public R<List<TreeNode>> all(){
        List<TreeNode> nodes = new ArrayList<>();
        List<DataSourceInfo> list = dataSourceInfoMapper.selectList(Wrappers.lambdaQuery(DataSourceInfo.class));
        for (DataSourceInfo ds : list) {
            TreeNode node = new TreeNode();
            node.setId(ds.getId());
            node.setLevel(1);
            node.setLabel(ds.getDbName());
            node.setChildren(Collections.emptyList());
            if ("mysql".equals(ds.getDataType())){
                node.setTag("M");
            }else if("oracle".equals(ds.getDataType())){
                node.setTag("O");
            }else if("db2".equals(ds.getDataType())){
                node.setTag("D");
            }else if("kingbase8".equals(ds.getDataType())){
                node.setTag("K");
            }
            nodes.add(node);
        }
        return R.ok(nodes);
    }

    @GetMapping("/getById")
    @ApiOperation("根据id获取数据源")
    public R<DataSourceInfo> getById(String id){
        return R.ok(dataSourceInfoMapper.selectById(id));
    }

    @PostMapping("/save")
    @ApiOperation("保存数据源配置")
    public R<DataSourceInfo> save(@RequestBody @Validated DataSourceInfo info){
        if (StrUtil.isNotBlank(info.getId())){
            dataSourceInfoMapper.updateById(info);
        }else {
            dataSourceInfoMapper.insert(info);
        }
        return R.ok(info,"操作成功!");
    }

    @GetMapping("/delete")
    @ApiOperation("删除数据源配置")
    public R<Boolean> delete(@NotBlank(message = "数据源id不能为空") String id){
        dataSourceInfoMapper.deleteById(id);
        return R.ok(null,"操作成功!");
    }

    @GetMapping("/copy")
    @ApiOperation("复制数据源")
    @Transactional(rollbackFor = Exception.class)
    public R<DataSourceInfo> copy(String id){
        DataSourceInfo info = dataSourceInfoMapper.selectById(id);
        info.setId(null);
        info.setDbName(info.getDbName() + "__Copy");
        dataSourceInfoMapper.insert(info);

        DatasourceStrategy ds = datasourceStrategyMapper.selectOne(
                Wrappers.lambdaQuery(DatasourceStrategy.class).eq(DatasourceStrategy::getDatasourceId, id)
        );
        if (ds != null){
            StrategyInfo strategy = strategyInfoMapper.selectById(ds.getStrategyId());
            if (strategy != null){
                strategy.setId(null);
                strategyInfoMapper.insert(strategy);

                ds.setId(null);
                ds.setStrategyId(strategy.getId());
                ds.setDatasourceId(info.getId());
                datasourceStrategyMapper.insert(ds);
            }
        }

        List<DatasourceFill> dfs = datasourceFillMapper.selectList(
                Wrappers.lambdaQuery(DatasourceFill.class).eq(DatasourceFill::getDatasourceId, id)
        );
        for (DatasourceFill df : dfs) {
            df.setId(null);
            df.setDatasourceId(info.getId());
            datasourceFillMapper.insert(df);
        }
        return R.ok(null,"操作成功!");
    }
}
